﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.ComponentModel;
using System.Drawing;

namespace Djs.Tools.FileCommander.Components
{
    [DataGridViewColumnDesignTimeVisible(false)]
    public partial class FileDataGrid : DataGridView
    {
        public FileDataGrid()
        {
            this.DoubleBuffered = true;

            this.Columns.Add("Name", "Name");
            this.Columns.Add("Ext", "Ext");
            this.Columns.Add("Size", "Size");
            this.Columns.Add("Date", "Date");

            this.Columns[0].Width = 320;
            this.Columns[1].Width = 70;
            this.Columns[2].Width = 100;
            this.Columns[2].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            this.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            this.Columns[3].Width = 120;

            this.BackgroundColor = Color.DarkBlue;

            this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
            this.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Sunken;
            this.ColumnHeadersHeight = 39;
            this.RowHeadersVisible = false;
            this.AllowUserToResizeRows = false;
            this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            this.CellBorderStyle = DataGridViewCellBorderStyle.None;
            this.DefaultCellStyle.Font = new Font("Cambria", 9f, FontStyle.Bold);
            this.DefaultCellStyle.BackColor = Color.DarkBlue;
            this.DefaultCellStyle.ForeColor = Color.LightYellow;
            this.EditMode = DataGridViewEditMode.EditProgrammatically;
            this.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            
        }
        public Color GetItemColor(FileSystem.FileItem fileItem)
        {
            return Color.Wheat;
        }
        public override void Sort(DataGridViewColumn dataGridViewColumn, System.ComponentModel.ListSortDirection direction)
        {
            base.Sort(dataGridViewColumn, direction);
        }

    }
    /// <summary>
    /// Jeden řádek s daty
    /// </summary>
    public class FileGridRow : DataGridViewRow
    {
        public FileGridRow(FileDataGrid grid, FileSystem.FileItem fileItem)
        {
            this.Grid = grid;
            this.FileItem = fileItem;
            this.Height = 18;
            string[] content = new string[4];
            string specName = null;
            string iconName = null;
            switch (fileItem.FileType)
            {
                case FileSystem.FileType.UpDir:
                    content[0] = "[..]";
                    content[1] = "";
                    content[2] = "<DIR>";
                    content[3] = "";
                    specName = FileIconStorage.SPEC_PREVIOUS;
                    break;
                case FileSystem.FileType.DownDir:
                    content[0] = "[" + fileItem.Name + "]";
                    content[1] = "";
                    content[2] = "<DIR>";
                    content[3] = fileItem.DateModify.ToString("dd.MM.yyyy HH:mm");
                    specName = FileIconStorage.SPEC_FOLDER;
                    break;
                case FileSystem.FileType.File:
                    content[0] = fileItem.Name;
                    content[1] = fileItem.Extension;
                    content[2] = fileItem.Length.ToString("### ### ### ###").Trim();
                    content[3] = fileItem.DateModify.ToString("dd.MM.yyyy HH:mm");
                    iconName = fileItem.FullName;
                    break;
            }
            this.Cells.Add(new FileGridImageCell(this) { SpecName = specName, IconName = iconName, Value = content[0], ValueType = typeof(string), ToolTipText = fileItem.FullName });
            this.Cells.Add(new FileGridImageCell(this) { Value = content[1], ValueType = typeof(string), ToolTipText = fileItem.FullName });
            this.Cells.Add(new FileGridImageCell(this) { Value = content[2], ValueType = typeof(string), ToolTipText = fileItem.FullName });
            this.Cells.Add(new FileGridImageCell(this) { Value = content[3], ValueType = typeof(string), ToolTipText = fileItem.FullName });

            // Nemá význam overridovat this.Visible, protože Grid na override get nereaguje, reaguje na base.Visible. Je tedy nutno hodnotu setovat do property:
            // this.Visible = (this.FileItem.FileType != FileSystem.FileType.File || this.FileItem.Name.StartsWith("c"));
        }
        public FileDataGrid Grid { get; private set; }
        public FileSystem.FileItem FileItem { get; private set; }
    }
    public class FileGridImageCell : DataGridViewTextBoxCell
    {
        public FileGridImageCell(FileGridRow row)
        {
            this.Row = row;
        }
        public FileDataGrid Grid { get { return this.Row.Grid; } }
        public FileGridRow Row { get; private set; }
        /// <summary>
        /// true pokud buňka má definován obrázek nebo prázdné odsazení na obrázek
        /// </summary>
        public bool HasImageColumn { get { return (this.SkipImage || !String.IsNullOrEmpty(this.IconName) || !String.IsNullOrEmpty(this.SpecName)); } }
        public string IconName { get; set; }
        public string SpecName { get; set; }
        public bool SkipImage { get; set; }
        #region Paint cell with/without a icon
        
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            this.Row.FileItem.StoreColorsForItem(cellStyle);
            if (!this.HasImageColumn)
                this.PaintWithoutImage(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
            else
                this.PaintWithImage(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
        }
        private void PaintWithoutImage(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
        }
        private void PaintWithImage(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            // Paint all except text, to whole bounds:
            DataGridViewPaintParts backParts = paintParts & (DataGridViewPaintParts.All ^ DataGridViewPaintParts.ContentForeground);
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, backParts);

            // Paint only text, to bounds after image (X + 18):
            Rectangle textBounds = new Rectangle(cellBounds.X + 18, cellBounds.Y, cellBounds.Width - 19, cellBounds.Height);
            DataGridViewPaintParts textParts = DataGridViewPaintParts.ContentForeground;
            base.Paint(graphics, clipBounds, textBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, textParts);

            // Paint only image:
            Rectangle imageBounds = new Rectangle(cellBounds.X + 1, cellBounds.Y + 1, 16, 16);
            StorageIconInfo iconInfo = ((this.SpecName != null) ? FileIconStorage.GetInfoForSpec(this.SpecName) : ((this.IconName != null) ? FileIconStorage.GetInfoForFile(this.IconName) : null));
            if (iconInfo != null)
            {
                if (iconInfo.HasBitmap)
                    graphics.DrawImage(iconInfo.Bitmap, imageBounds);
                else if (iconInfo.HasIcon)
                    graphics.DrawIcon(iconInfo.Icon, imageBounds);
            }
        }
        #endregion

        protected override void OnKeyDown(KeyEventArgs e, int rowIndex)
        {
            if ((e.Modifiers & Keys.Alt) != 0 && e.KeyValue != 0 && e.KeyValue != 18 && e.KeyValue != 115)        // 18: samotný Alt; 115={Alt+F4}
            {
                this.Grid.FirstDisplayedScrollingRowIndex++;
                e.Handled = true;
                e.SuppressKeyPress = true;
            }
            base.OnKeyDown(e, rowIndex);
        }
    }
}
